package com.liuyi.netty.im.lychat.config.base;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.liuyi.rapid.develop.mybatis.PageRespUtil;
import com.liuyi.rapid.develop.mybatis.plus.base.IBaseService;
import com.liuyi.rapid.develop.mybatis.plus.condition.QueryCondition;
import com.liuyi.rapid.develop.tool.resp.Response;
import com.liuyi.rapid.develop.tool.resp.ResponseCall;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

/**
 * <p>
 * 公用查询
 * </p>
 *
 * @author Mr.Fmy
 * @since 2021-02-02
 */
public interface BaseQueryController<T, S extends IBaseService<T>> extends BaseController<T, S> {

    @ApiOperation(value = "按id查询", notes = "参数为id", httpMethod = "GET")
    @GetMapping("/get/{id}")
    default Response<T> get(@PathVariable Serializable id) {
        QueryWrapper<T> q = server().q();
        return around(q, "get", () -> {
            q.eq("id", id);
            return ResponseCall.success(server().getOne(q));
        });
    }

    @ApiOperation(value = "分页查询", notes = "不传page,limit，默认会分页", httpMethod = "POST")
    @PostMapping("/listPage")
    default Response<List<T>> listPage(@RequestBody QueryCondition condition) {
        if (condition.getSort().isEmpty()) {
            sort(condition.getSort());
        }
        QueryWrapper<T> q = server().analysisQ(condition);
        return around(q, "listPage", () -> PageRespUtil.page(condition.getPage(), condition.getLimit(), () -> server().list(q)));
    }

    //    @ApiOperation(value = "列表查询", notes = "和listPage入参相同，就算传了page,limit也不会分页，会返回所有", httpMethod = "POST")
    @PostMapping("/list")
    default Response<List<T>> list(@RequestBody QueryCondition condition) {
        if (condition.getSort().isEmpty()) {
            sort(condition.getSort());
        }
        QueryWrapper<T> q = server().analysisQ(condition);
        return around(q, "list", () -> ResponseCall.success(server().list(q)));
    }

    @SuppressWarnings("unchecked")
    default <R> Response<R> around(QueryWrapper<T> wrapper, String method, Supplier<Response<R>> supplier) {
        try {
            TimeInterval timer = DateUtil.timer();
            pre(wrapper, method);
            Response<R> response = supplier.get();
            R data = response.getData();
            if (data != null) {
                if (data instanceof Collection) {
                    ((Collection<?>) data).forEach(item -> wrapper((T) item));
                    wrapperList((List<T>) data);
                } else {
                    wrapper((T) data);
                    wrapperOne((T) data);
                }
            }
            System.out.println(timer.intervalMs());
            return response;
        } finally {
            finallyExec(method);
        }
    }

    /**
     * 前置执行
     */
    default void pre(QueryWrapper<T> wrapper, String method) {

    }

    /**
     * finally 执行
     */
    default void finallyExec(String method) {

    }

    /**
     * 针对于 单条数据 wrapper
     */
    default void wrapperOne(T data) {

    }


    /**
     * 针对于 多条数据 wrapper
     */
    default void wrapperList(List<T> datas) {

    }

    /**
     * 针对于 所有数据 wrapper
     */
    default void wrapper(T data) {

    }

    /**
     * 默认的排序方式
     * <pre>
     *     只有不存在排序的时候才会调用该方法
     * </pre>
     */
    default void sort(Map<String, String> sort) {
        sort.put("ORDER_createTime", "desc");
    }
}
